"""
新闻情绪分析策略(Zipline实现)
策略逻辑：
1. 模拟新闻情绪分析（实际实现需外部数据源）
2. 根据情绪变化生成交易信号
3. 结合技术指标确认信号
"""

from zipline.api import order_target_percent, record, symbol, get_datetime
from zipline.finance import commission, slippage
import numpy as np
import pandas as pd

def initialize(context):
    # 策略参数
    context.asset = symbol('AAPL')
    context.lookback = 20  # 20日均线
    context.sentiment_threshold = 0.5
    
    # 设置交易成本
    context.set_commission(commission.PerShare(cost=0.001, min_trade_cost=1))
    context.set_slippage(slippage.FixedSlippage(spread=0.01))
    
    # 初始化状态
    context.position = 0
    context.sentiment_history = []

def simulate_sentiment(data):
    """模拟新闻情绪分析（实际实现需外部数据源）"""
    # 在实际应用中，这里应该调用外部API获取新闻情绪数据
    # 这里我们使用随机数据来模拟
    return np.random.uniform(-1, 1)

def handle_data(context, data):
    # 获取当前价格
    current_price = data.current(context.asset, 'price')
    
    # 获取历史价格计算20日均线
    prices = data.history(context.asset, 'price', context.lookback, '1d')
    ma20 = prices.mean()
    
    # 模拟新闻情绪分析
    sentiment = simulate_sentiment(data)
    context.sentiment_history.append(sentiment)
    
    # 保持历史数据长度
    if len(context.sentiment_history) > 7:
        context.sentiment_history.pop(0)
    
    # 计算7日平均情绪指数
    sentiment_index = np.mean(context.sentiment_history) if context.sentiment_history else 0
    
    # 生成信号
    signal = 0
    # 多头信号: 情绪积极且价格在20日均线上方
    if sentiment_index > context.sentiment_threshold and current_price > ma20:
        signal = 1
    # 空头信号: 情绪消极且价格在20日均线下方
    elif sentiment_index < -context.sentiment_threshold and current_price < ma20:
        signal = -1
    # 平仓信号: 情绪中性或价格与均线关系变化
    elif abs(sentiment_index) < 0.3 and context.position != 0:
        signal = 0
    
    # 执行交易
    if signal == 1 and context.position <= 0:
        order_target_percent(context.asset, 1.0)
        context.position = 1
    elif signal == -1 and context.position >= 0:
        order_target_percent(context.asset, -1.0)
        context.position = -1
    elif signal == 0 and context.position != 0:
        order_target_percent(context.asset, 0)
        context.position = 0
    
    # 记录状态
    record(price=current_price, 
          ma20=ma20, 
          sentiment=sentiment_index, 
          position=context.position)